# coding=utf-8
import random
import re
from datetime import datetime

from flask import current_app
from flask import make_response, jsonify
from flask import request
from flask import session


from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blu


# from flask_wtf.csrf import generate_csrf
# @passport_blu.route('/')
# def passport():
#     return 'abc'
# 生成验证码以及图像 保存到redis 返回给浏览器
# url:/image_code
# 请求方式GET
# 浏览器发来的参数image_code_id


@passport_blu.route('/logout', methods=['POST'])
def logout():
    """清除session中对应登录之后保存的信息"""
    session.pop('user_id', None)
    session.pop('user_nick_name', None)
    session.pop('user_mobile', None)
    session.pop('is_admin', None)

    return jsonify(errno=RET.OK, errmsg='ok')


@passport_blu.route('/login', methods=['POST'])
def login():
    # 1.获取参数 moblie password
    # 2.验证参数 完整性 手机号正则
    # 3.查询数据库中有没有该手机号
    json_data = request.json
    mobile = json_data.get('mobile')
    password = json_data.get('password')

    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不全')
    if not re.match('1[345678][0-9]{9}', mobile):
        return jsonify(error=RET.DATAERR, errmsg='手机号格式不正确')

    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询数据库失败')

    # if not user or user.password_hash != password:
    if not user or not user.check_passowrd(password):
        return jsonify(errno=RET.DATAEXIST, errmsg='用户不存在或密码错误')

    # 设置最后登录时间
    user.last_login = datetime.now()
    # try:
    #     db.session.commit()
    # except Exception as e:
    #     current_app.logger.error(e)
    #     db.session.rollback()
    session['user_id'] = user.id
    session['user_nick_name'] = user.nick_name
    session['user_mobile'] = user.mobile

    return jsonify(errno=RET.OK, errmsg='登陆成功')


@passport_blu.route('/image_code')
def get_image_code():
    # 1.获取浏览器发来的参数image_code_id  为了保存到redis使用 当作key
    image_code_id = request.args.get('image_code_id')
    # 2.生成验证码以及图像
    name, text, image_data = captcha.generate_captcha()
    # 3.保存到redis
    try:
        redis_store.set('ImageCodeId_'+image_code_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存到redis出错')
    # 4.返回数据
    resp = make_response(image_data)
    resp.headers['Content-Type'] = 'image/jpg'
    return resp


# 获取短信验证码
# url:/sms_code
# 请求方式post
# 浏览器发来的参数 mobile image_code  image_code_id
@passport_blu.route('/sms_code', methods=['POST'])
def get_sms_code():
    # 一 获取数据
    # 1.获取请求参数
    json_data = request.json
    mobile = json_data.get('mobile')
    image_code = json_data.get('image_code')
    image_code_id = json_data.get('image_code_id')

    # 二检验数据
    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

    if not re.match('1[345678][0-9]{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg='手机号错误')

    # 2.从redis中读数据  对比数据 图片验证码
    try:
        real_image_code = redis_store.get('ImageCodeId_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询redis错误')

    # 判空处理
    if not real_image_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码已过期')

    # 删除图像验证码
    try:
        redis_store.delete('ImageCodeId_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='redis删除失败')

    # 将两个数据对比：对比失败返回json数据
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg='验证码填写错误')

    # 验证手机号有没有被注册过
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询mysql数据库失败')

    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='该用户已经注册过')

    # 4.验证图片验证码成功  生成短信验证码  短信验证码由自己生成 云通讯不生成验证码
    sms_code_str = '%06d' % random.randint(0, 999999)
    print(sms_code_str)

    # 把短信验证码保存到redis中
    try:
        redis_store.set('SMS_'+mobile, sms_code_str, constants.SMS_CODE_REDIS_EXPIRES)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存短信验证码失败')

    # 调用云通信发短信
    # 数字5 短信验证码过期时间
    # result = CCP().send_template_sms(mobile, [sms_code_str, 5], 1)
    # if result != 0:
    #     return jsonify(errno=RET.THIRDERR, errmsg='发送短信验证码失败')

    # 发送成功，返回json数据
    return jsonify(errno=RET.OK, errmsg='发送短信验证码成功')


# 注册功能实现
# 从前端获取数据 手机号 用户输入的短信验证码 密码
# 判断用户是否全部输入
# 从redis中获取手机号对应的验证码
# 校检验证码
@passport_blu.route('/register', methods=['POST'])
def register():
    # 1.获取参数和判断是否有值
    json_data = request.json
    mobile = json_data.get('mobile')
    sms_code = json_data.get('sms_code')
    password = json_data.get('password')

    # 2.检测数据
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.DATAERR, errmsg='参数不全')
    if not re.match('1[3456789][0-9]{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg='手机号格式不正确')

    # 3.从redis中取出短信验证码
    try:
        real_sms_code = redis_store.get('SMS_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='读取本地验证码出错')

    if not real_sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码失效')

    if real_sms_code != sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='验证码输入错误')

    # 删除短信验证码
    try:
        redis_store.delete('SMS_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        # return jsonify(errno=RET.DATAERR, errmsg='删除验证码错误')
    # 查询手机号有没有注册过
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询mysql数据库失败')

    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='已经注册，请直接登陆')

    # 初始化user模型
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    # 对密码进行处理 #
    # user.password_hash = password
    user.password = password
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        # 数据库修改操作，失败了需要回滚
        db.session.rollback()
        return jsonify(errno=RET.DATAERR, errmsg='提交数据失败')

    # 保存用户登陆状态
    session['user_id'] = user.id
    session['user_nick_name'] = user.nick_name
    session['user_mobile'] = user.mobile

    return jsonify(errno=RET.OK, errmsg='注册成功')

